/**     
 * @{#} MemcachedClient.java Create on 2011-7-24 下午02:48:50     
 *     
 * Copyright (c) 2011 by xiaofeng.zhouxf     
 */
package com.sefer.memcached.client;

import com.sefer.memcached.command.AddCommand;
import com.sefer.memcached.command.Command;
import com.sefer.memcached.command.DelCommand;
import com.sefer.memcached.command.GetCommand;
import com.sefer.memcached.connect.Server;
import com.sefer.memcached.constants.ErrorCode;
import com.sefer.memcached.exception.ClientException;

/**
 * @author <a href="mailto:xiaofeng.zhouxf83@gmail.com">xiaofeng.zhouxf</a>
 * @version 1.0
 */
public class MemcachedClient {

	private Client client;
	private String[] ips;
	private String[] ports;

	/**
	 * <pre>
	 * Initialization the client.
	 * 
	 * </pre>
	 * 
	 * @param ips
	 *            server's ips
	 * @param ports
	 *            server's ports
	 * @param isToConnect
	 *            connect the server
	 * @throws ClientException
	 *             <p>
	 *             if pararms error while throw ClientException with ErrorCode
	 *             E_1xx.
	 *             <p>
	 *             if socket connect error while throw ClientException with
	 *             ErrorCode E_4xx
	 */
	// @NotThreadSafe
	public MemcachedClient(String[] ips, String[] ports, boolean isToConnect) {
		super();
		this.ips = ips;
		this.ports = ports;
		if (isToConnect) {
			this.connect();
		}
	}

	/**
	 * <pre>
	 * Initialization the client.
	 * 
	 * </pre>
	 * 
	 * @param ips
	 *            server's ips
	 * @param ports
	 *            server's ports
	 * @param isToConnect
	 *            connect the server
	 * @throws ClientException
	 *             <p>
	 *             if pararms error while throw ClientException with ErrorCode
	 *             E_1xx.
	 *             <p>
	 *             if socket connect error while throw ClientException with
	 *             ErrorCode E_4xx
	 */
	// @NotThreadSafe
	public MemcachedClient(String[] servers, boolean isToConnect) {
		super();

		if (servers == null || servers.length == 0) {
			throw new ClientException(ErrorCode.E_100,
					"Server information can't be null");
		}
		this.ips = new String[servers.length];
		this.ports = new String[servers.length];

		for (int i = 0; i < servers.length; i++) {
			String[] split = servers[i].split(":");
			ips[i] = split[0];
			ports[i] = split[1];
		}

		if (isToConnect) {
			this.connect();
		}
	}

	/**
	 * <pre>
	 * Initialization the client.Input params must format as this :
	 * {
	 *  ip1,port1,ip2,port2 ...
	 * }
	 * 
	 * So you can use this method like this:
	 * <code>
	 * String server1="127.0.0.1:11211";
	 * String server2="192.168.1.1:11211";
	 * String server3="192.168.1.2:11211";
	 * 
	 * 
	 * MemcachedClient client = new MemcachedClient(server1,server2,server3);
	 * </code>
	 * 
	 * Notice:
	 *   This method will connect to de server as default.
	 * </pre>
	 * 
	 * @param params
	 *            {ip,port,ip,port,..}
	 * @throws ClientException
	 *             <p>
	 *             if pararms error while throw ClientException with ErrorCode
	 *             E_1xx
	 *             <p>
	 *             if socket connect error while throw ClientException with
	 *             ErrorCode E_4xx
	 */
	public MemcachedClient(String... servers) {
		if (servers == null || servers.length == 0) {
			throw new ClientException(ErrorCode.E_100,
					"Server information can't be null");
		}
		this.ips = new String[servers.length];
		this.ports = new String[servers.length];

		for (int i = 0; i < servers.length; i++) {
			String[] split = servers[i].split(":");
			ips[i] = split[0];
			ports[i] = split[1];
		}

		this.connect();
	}

	private void connect() {
		this.client = new Client();
		Server[] servers = new Server[1];
		for (int i = 0; i < ips.length; i++) {
			servers[0] = new Server(ips[i], Integer.valueOf(ports[i]));
		}
		client.init(servers);
		client.start();
	}

	public boolean put(String key, String message) {
		Command command = new AddCommand(key, message);
		// System.out.println(command.getResult());
		return client.callServer(command);
	}

	public String get(String key) {
		Command command = new GetCommand(key);
		client.callServer(command);
		return command.getResult();
	}

	public boolean delete(String key) {
		Command command = new DelCommand(key);
		return client.callServer(command);
	}

	public void stop() {
		this.client.stop();
	}
}
